package com.hserver.system.service;

import com.hserver.system.entity.ConfigEntity;
import com.hserver.system.entity.PermissionEntity;
import com.hserver.system.entity.RoleEntity;
import com.hserver.system.entity.UserEntity;
import com.hserver.system.mapper.UserMapper;
import com.hserver.system.utils.PageView;
import com.hserver.system.utils.RedisUtil;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import redis.clients.jedis.Jedis;
import top.hserver.core.ioc.annotation.Autowired;
import top.hserver.core.ioc.annotation.Bean;
import top.hserver.core.server.util.JsonResult;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Bean
public class UserService {

    @Autowired
    private SqlSessionFactory sqlSessionFactory;
    @Autowired
    private ConfigService configService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private PermissionService permissionService;

    public JsonResult login(UserEntity param) {
        JsonResult result = JsonResult.ok();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        UserEntity userEntity = userMapper.login(param);
        sqlSession.close();
        if (userEntity != null) {
            if (tokenService.hasToken(param.getUsername())) {
                String token = tokenService.getToken(param.getUsername());
                Map map = new HashMap();
                map.put("token", token);
                map.put("userInfo", userEntity);
                result.put("success", true);
                result.put("result", map);
                return result;
            } else {
                String token = tokenService.newToken(userEntity);
                Map map = new HashMap();
                map.put("token", token);
                map.put("userInfo", userEntity);
                result.put("success", true);
                result.put("result", map);
                return result;
            }
        } else {
            return JsonResult.error("用户名/密码错误");
        }
    }

    public void buildRef(PermissionEntity evalEntity, List<PermissionEntity> evalEntities) {
        for (int i = 0; i < evalEntities.size(); i++) {
            PermissionEntity ee = evalEntities.get(i);
            if (ee.getParentId() != null) {
                if (ee.getParentId() == evalEntity.getId()) {
                    if (evalEntity.getChildren() == null) {
                        evalEntity.setChildren(new ArrayList<>());
                    }
                    evalEntity.getChildren().add(ee);
                    buildRef(ee, evalEntities);
                }
            }
        }
    }

    public void removeChild(List<PermissionEntity> evalEntities) {
        for (int i = 0; i < evalEntities.size(); i++) {
            PermissionEntity ee = evalEntities.get(i);
            if (ee.getParentId() != null) {
                evalEntities.remove(ee);
                i--;
            }
        }
    }

    public List<PermissionEntity> getUserPermission(String username) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<PermissionEntity> permissionEntities = userMapper.getUserPermission(username);
        sqlSession.close();
        for (int i = 0; i < permissionEntities.size(); i++) {
            Map mate = new HashMap();
            mate.put("title", permissionEntities.get(i).getName());
            mate.put("icon", permissionEntities.get(i).getIcon());
            mate.put("keepAlive", true);
            permissionEntities.get(i).setMeta(mate);
            if (permissionEntities.get(i).getParentId() == null) {
                buildRef(permissionEntities.get(i), permissionEntities);
            }
        }
        removeChild(permissionEntities);
        return permissionEntities;
    }

    public JsonResult logout(UserEntity param) {
        JsonResult result = JsonResult.ok();
        ConfigEntity p = configService.getConfig();
        if ("sql".equals(p.getTokenLocation())) {
            SqlSession sqlSession = sqlSessionFactory.openSession();
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            userMapper.logout(param);
            sqlSession.close();
        } else {
            String token = redisUtil.get("user:token:" + param.getUsername());
            redisUtil.del("user:info:" + token);
            redisUtil.del("user:token:" + param.getUsername());
        }
        return JsonResult.ok();
    }

    public PageView page(UserEntity userEntity) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        int totalCont = userMapper.cont(userEntity);
        List<UserEntity> userEntities = userMapper.list(userEntity);
        sqlSession.close();
        PageView pageView = PageView.of(totalCont, userEntity.getPageSize(), userEntity.getPageNo(), userEntities);
        return pageView;
    }

    public JsonResult checkUsername(String username) {
        JsonResult jsonResult = JsonResult.ok();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<UserEntity> userEntity = userMapper.list(new UserEntity() {{
            setUsername(username);
        }});
        sqlSession.close();
        if (userEntity.size() > 0) {
            jsonResult.put("success", false);
            return jsonResult;
        }
        jsonResult.put("success", true);
        return jsonResult;
    }

    public JsonResult add(UserEntity userEntity) {
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        //sqlSession.getConfiguration().
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        userMapper.insert(userEntity);
        int userId = userMapper.getLastId();
        if (userEntity.getSelectedroles() != null) {
            String[] roles = userEntity.getSelectedroles().split(",");
            for (int i = 0; i < roles.length; i++) {
                if (roles[i] != null && !"".equals(roles[i])) {
                    userMapper.insertRole(userId, Integer.valueOf(roles[i]));
                }
            }
        }
        sqlSession.commit();
        sqlSession.close();
        //userMapper.delRoles(userEntity.);
        JsonResult jsonResult = JsonResult.ok();
        jsonResult.put("success", true);
        return jsonResult;
    }

    public JsonResult edit(UserEntity userEntity) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        userMapper.update(userEntity);
        userMapper.delRole(userEntity.getId());
        if (userEntity.getSelectedroles() != null) {
            String[] roles = userEntity.getSelectedroles().split(",");
            for (int i = 0; i < roles.length; i++) {
                if (roles[i] != null && !"".equals(roles[i])) {
                    userMapper.insertRole(userEntity.getId(), Integer.valueOf(roles[i]));
                }
            }
        }
        sqlSession.commit();
        sqlSession.close();
        //
        JsonResult jsonResult = JsonResult.ok();
        jsonResult.put("success", true);
        return jsonResult;
    }

    public JsonResult deleteById(Integer id) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        userMapper.deleteById(id);
        sqlSession.commit();
        sqlSession.close();
        JsonResult jsonResult = JsonResult.ok();
        jsonResult.put("success", true);
        return jsonResult;
    }

    public JsonResult deleteBatch(String[] id) {
        if (id != null) {
            for (int i = 0; i < id.length; i++) {
                if (id[i] != null && !"".equals(id[i])) {
                    deleteById(Integer.valueOf(id[i]));
                }
            }
        }
        JsonResult jsonResult = JsonResult.ok();
        jsonResult.put("success", true);
        return jsonResult;
    }

    public JsonResult queryUserRole(Integer userid) {
        JsonResult jsonResult = JsonResult.ok();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<RoleEntity> roles = userMapper.queryRole(userid);
        sqlSession.close();
        List roleId = new ArrayList();
        if (roles != null) {
            for (RoleEntity roleEntity : roles) {
                roleId.add(roleEntity.getId());
            }
        }
        jsonResult.put("result", roleId);
        jsonResult.put("success", true);
        return jsonResult;
    }
}
